package org.springframework.zp.mybatis.demo.util;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;

import java.util.Map;
import java.util.Set;

/**
 * 用于模拟  @MapperScan 注解引入的 @Import(MapperScannerRegistrar.class)
 */
@Slf4j(topic = "e")
public class MyImportBeanDefinitionRegistart implements ImportBeanDefinitionRegistrar {

	/**
	 * 扫描出来的 Bean Definition Holder 即对应的是 Mapper 接口
	 */
	Set<BeanDefinitionHolder> beanDefinitionHolders = null;

	/**
	 * 实现扫包并完成注入过程
	 *
	 * @param importingClassMetadata annotation metadata of the importing class
	 * @param registry current bean definition registry
	 */
	@Override
	public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry){
		/**
		 * 获得注解的对应的属性信息
		 *
		 * 完成了扫描 --put bdmap  会多两个 BeanDefinition
		 */
		Map<String, Object> annotationAttributes = importingClassMetadata.getAnnotationAttributes(MyScan.class.getName());

		// 扫包
		scan(registry,annotationAttributes);

		/**
		 * 针对 BeanDefinition 进行处理，实现替换代理类
		 */
		for (BeanDefinitionHolder beanDefinitionHolder : beanDefinitionHolders) {
			// 获得  Bean Definition
			AbstractBeanDefinition mapperBd = (AbstractBeanDefinition) beanDefinitionHolder.getBeanDefinition();
			String beanClassName = mapperBd.getBeanClassName();

			// 调用自己 MyFactoryBean 创建代理类
			mapperBd.setBeanClass(MyFactoryBean.class);
			mapperBd.getPropertyValues().add("mapperInterface",beanClassName);
		}
	}

	/**
	 * 根据注解里面的配置的包路径进行扫包
	 *
	 * @param registry
	 * @param annotationAttributes
	 */
	private void scan(BeanDefinitionRegistry registry,Map<String, Object> annotationAttributes){
		// 获得需要扫描的包路径
		String scanPackageName = (String) annotationAttributes.get("value");

		// 调用自定义的扫包代码
		MyMapperScaner scaner = new MyMapperScaner(registry,true);

		beanDefinitionHolders = scaner.doScan(scanPackageName);

	}


}
